home *** CD-ROM | disk | FTP | other *** search
- page 77, 132
- title MONO.ASM - monochrome screen driver - 03/06/88
-
- comment @
- Written by Rick Richard, CompuServ ID#72560,2702
-
- IMPROVEMENTS NEEDED:
- 1) BEEP function
- 2) positioning of cursor after print
- 3) destructive backspace
- 4) detect for mono on load, don't load if not present
- comment @
-
- cseg segment para public 'code'
- mono proc far
- assume cs:cseg, es:cseg, ds:cseg
- org 0 ;
-
- reqhdr struc ;fixed request header structure
- reqhdr_len db ? ; len of packet
- reqhdr_unit db ? ; unit code, block devices only
- reqhdr_cmd db ? ; device driver comand
- reqhdr_status dw ? ; returned by device driver
- reqhdr_res1 dd ? ; reserved
- reqhdr_res2 dd ? ; reserved
- reqhdr ends
-
- reqhdr0 struc ;request header for Initialization (command 0)
- reqhdr0_fixed db size reqhdr dup(?) ; fixed request header portion
- reqhdr0_nunits db ? ; number of units
- reqhdr0_brk_ofs dw ? ; offset address for break
- reqhdr0_brk_seg dw ? ; segment address for break
- reqhdr0_bpb_tbo dw ? ; offset address of pointer to BPB array
- reqhdr0_bpb_tbs dw ? ; segment address of pointer to BPB array
- reqhdr0_drv_ltr db ? ; first available drive (DOS 3+) block only
- reqhdr0 ends
-
- reqhdr8 struc ;request header for output (command 8)
- reqhdr8_fixed db size reqhdr dup(?) ; fixed request header portion
- reqhdr8_media db ? ; media descriptor from DPB
- reqhdr8_buf_ofs dw ? ; offset address of data transfer area
- reqhdr8_buf_seg dw ? ; segment address of data transfer area
- reqhdr8_count dw ? ; transfer count in bytes
- reqhdr8_start dw ? ; start sector number (block only)
- reqhdr8 ends
-
- ;;;; MAIN ;;;;
-
- begin:
-
- ;;;; DEVICE HEADER ;;;;
-
- next_dev dd -1 ; no other drivers
- attribute dw 8000h ; character, output, input
- strategy dw dev_strategy ; strategy routine address
- interrupt dw dev_interrupt ; interrupt routine address
- dev_name db 'MONOSCR ' ; name of device driver
- db '$'
- ;;;; WORK SPACE ;;;;
-
- cursor_row db 0
- cursor_col db 0
- scr_cols dw 80
- reqhdr_ofs dw ? ; offset address of the request header
- reqhdr_seg dw ? ; segment address of the request header
-
- ;;;; STRATEGY PROCEDURE ;;;
-
- dev_strategy:
- mov cs:reqhdr_seg, es ; save the segment address
- mov cs:reqhdr_ofs, bx ; save the offset address
- ret ; return to DOS
-
- ;;;; INTERRUPT PROCEDURE ;;;;
-
- dev_interrupt:
- cld
- push ds
- push es
- push ax
- push bx
- push cx
- push dx
- push di
- push si
-
- mov ax, cs:reqhdr_seg ; restore ES as saved by strategy procedure
- mov es, ax
- mov bx, cs:reqhdr_ofs ; restore BX as saved by strategy procedure
-
- ;;; JUMP TO ROUTINE TO PROCESS COMMAND ;;;
-
- mov al, es:[bx].reqhdr_cmd
- rol al, 1
- lea di, cmdtab
- mov ah, 0
- add di, ax
- jmp word ptr[di]
-
- CMDTAB label byte
- dw INITIALIZATION
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
- dw OUTPUT
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
- dw NOT_SUPPORTED
-
- ;;;; LOCAL PROCEDURES ;;;;
-
- beep proc near
- ret
- beep endp
-
-
- position proc near
- push bx
- mov bx, ax
- mov al, ah
- mul byte ptr cs:scr_cols
- xor bh, bh
- add ax, bx
- sal ax, 1
- pop bx
- ret
- position endp
-
- scroll_up proc near
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push bp
- push ds
-
- mov ah, 7
- mov al, 1
- mov bx, 0701h
- mov cx, 0
- mov dh, 24
- mov dl, 79
-
- n1:
- push bx
- mov ax, cx
- call scroll_position
- jz n7
- add si, ax
- mov ah, dh
- sub ah, bl
- n2:
- call n10
- add si, bp
- add di, bp
- dec ah
- jnz n2
- n3:
- pop ax
- mov al, ' '
- n4:
- call n11
- add di, bp
- dec bl
- jnz n4
- n5:
- n6:
- pop ds
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- n7:
- mov bl, dh
- jmp n3
- ret
- scroll_up endp
-
-
-
- scroll_position proc near
- n9:
- call position
- mov di, ax
- mov si, ax
- sub dx, cx
- inc dh
- inc dl
- xor ch, ch
- mov bp, cs:scr_cols
- add bp, bp
- mov al, bl
- mul byte ptr cs:scr_cols
- add ax, ax
- push es
- pop ds
- cmp bl, 0
- ret
- scroll_position endp
-
-
- n10 proc near
- mov cl, dl
- push si
- push di
- rep movsw
- pop di
- pop si
- ret
- n10 endp
-
- n11 proc near
- mov cl, dl
- push di
- rep stosw
- pop di
- ret
- n11 endp
-
-
- write_char proc near
- push ax
- push bx
- push cx
- push dx
-
- mov dh, cs:cursor_row ; y
- mov dl, cs:cursor_col ; x
-
- ;---- DX NOW HAS THE CURRENT CURSOR POSITION
-
- cmp al, 08h ; is it a BACKSPACE
- je u8 ; BACKSPACE
- cmp al, 0dh ; is it a CARRIAGE RETURN
- je u9 ; CAR_RET
- cmp al, 0ah ; is it a LINE FEED
- je u10 ; LINE_FEED
- cmp al, 07h ; is it a BELL
- je u11 ; BELL
- cmp al, 0ch ; is it a FORM FEED
- je u12 ; FORM_FEED
- cmp al, 09h ; is it a TAB
- je u13 ; TAB
-
-
- ;---- WRITE THE CHAR TO THE SCREEN
-
- push ax ; save character
- mov ax, dx ; row/col
- call position ; calculate screen position
- mov di, ax
- pop ax ; retrieve character
- mov ah, 7 ; set attribute
- stosw ; write the character
-
- ;--- POSITION THE CURSOR FOR NEXT CHAR
-
- repos: inc dl ; increment column
- cmp dl, 80 ; test for column overflow
- jl exit ; SET_CURSOR
- mov dl, 0 ; column for cursor
- cmp dh, 24
- jl set_c_exit ; SET_CURSOR_INC
-
- ;---- SCROLL REQUIRED
-
- call scroll_up
- jmp SHORT exit
-
- set_c_exit:
-
- inc dh
- jmp SHORT exit
-
- ;---- BACK SPACE FOUND
-
- u8:
- cmp dl, 0 ; already at end of line
- je exit ; set_cursor
- dec dl ; no, just move it back
- jmp SHORT exit ; set_cursor
-
- ;---- CARRIAGE RETURN FOUND
-
- u9:
- mov dl, 0 ; move to first column
- jmp SHORT exit ; set_cursor
-
- ;---- LINE FEED FOUND
-
- u10:
- cmp dh, 24 ; bottom of screen
- jne set_c_exit ; yes, scroll the screen
- call scroll_up
- jmp SHORT exit
-
- ;---- BELL FOUND
-
- u11:
- call beep ; sound the bell
- jmp SHORT exit ; write_char return
-
- ;----FORM FEED FOUND
-
- u12:
- mov dx, 0 ; reset the cursor position
- mov cx, 2000 ; repeat count
- mov ax, 0700h ; attribute and color
- mov di, 0 ; starting screen position
- rep stosw
- jmp SHORT exit
-
- ;----TAB CHARACTER FOUND
- u13:
- mov ax, dx ; row/col
- call position ; calculate screen position
- mov di, ax
- mov ax, 720h ; set character and attribute
- nxttab: stosw ; write the character
- inc dl ; increment column
- test dl, 07h ; test for ?????111
- jnz nxttab ; when not all zeros - continue
- dec dl
- jmp repos ; go for next character
-
- exit:
- mov cs:cursor_row, dh
- mov cs:cursor_col, dl
- pop dx
- pop cx
- pop bx
- pop ax
- ret ; return to caller
-
- write_char endp
-
- ;;;; DOS COMMAND PROCESSING ;;;;
-
- Initialization: ; command 0
- call initial
- lea ax, initial
- mov es:[bx].reqhdr0_brk_ofs, ax ; Ending offset for this device driver
- mov es:[bx].reqhdr0_brk_seg, cs ; Ending segment for this device driver
- jmp SHORT done
-
-
- Output: ; command 8
- push ds
- mov cx, es:[bx].reqhdr8_count
- mov si, es:[bx].reqhdr8_buf_ofs
- mov ax, es:[bx].reqhdr8_buf_seg
- mov ds, ax
- mov bx, 0
- mov ax, 0b000h ; monochrome screen
- mov es, ax
- cld
- out1:
- mov al, ds:[si]
- inc si
- call write_char
- loop out1
-
- mov ax, cs:reqhdr_seg
- mov es, ax
- mov bx, cs:reqhdr_ofs
- pop ds
- jmp SHORT done
-
- ;;;;;;;;;;;;;;;;;;;;;; UNUSED DEVICE FUNCTIONS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- NOT_SUPPORTED:
- jmp SHORT done
-
- unknown:
- or es:[bx].reqhdr_status, 8003h
- jmp SHORT done1
-
- busy:
- or es:[bx].reqhdr_status, 0200h
- jmp SHORT done1
-
- done:
- or es:[bx].reqhdr_status, 0100h
-
- done1:
- pop si
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- pop es
- pop ds
- ret
-
-
- initial proc near
- push ax
- push dx
-
- ;;; PRINT SIGN-ON BANNER ;;;
- lea dx, BANNER
- mov ah, 9
- int 21h
- cld
-
- pop dx
- pop ax
-
- ret
- initial endp
-
- BANNER db 0AH, 0DH, '┌───────────────────────────────────────┐'
- db 0AH, 0DH, '│ Monochrome Screen Driver V1.0 │'
- db 0AH, 0DH, '│ Device Name: MONOSCR │'
- db 0AH, 0DH, '│ Written By : Rick Richard, 3/6/88 │'
- db 0AH, 0DH, '└───────────────────────────────────────┘'
- db 0AH, 0DH, '$'
- BANNER_SIZE EQU $-BANNER
-
- mono endp
- cseg ends
- end begin
-